package io.linfeng.common.utils;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.converts.OracleTypeConvert;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MybatisPlusGenerator {

    //    private static final String tableNames = "MES_PCS_STAMPING_GAUGES_11,MES_PCS_STAMPING_GAUGES_2,MES_PCS_STAMPING_GAUGES_3,MES_PCS_STAMPING_GAUGES_21,MES_PCS_STAMPING_GAUGES_41,MES_PCS_STAMPING_GAUGES_61,MES_PCS_STAMPING_GAUGES_62,MES_PCS_DOOR_CLOSING_SPEED,MES_PCS_HANDBREAK_TENSILE,MES_PCS_CLUTCH_PEDAL_FORCE,MES_PCS_CONDITIONER_OUTLET,MES_PCS_BATTERY_VOLTAGE,MES_PCS_VEHICLE_WEIGHING,MES_PCS_TIRE_PRESSURE,MES_PCS_INTENSIVE_RAIN,MES_PCS_AIR_TIGHTNESS,MES_PCS_GLASS_SPEED,MES_PCS_WIPER_ANGLE_PRESSURE,MES_PCS_FOUR_WHEEL_POSITION,MES_PCS_SEAL_MEASUREMENT,MES_PCS_TRAVEL_ALTITUDE,MES_PCS_STEERINGWHEEL_ANGLE,MES_PCS_STEERINGWHEEL_TORQUE,MES_PCS_GAP_RECORD,MES_PCS_SEGMENT_RECORD,MES_PCS_HEADLIGHT_DETECTION,MES_PCS_CONTOUR_SIZE,MES_PCS_RADAR_RANGE,MES_PCS_WHEELBASE,MES_PCS_FOUR_DOOR_TENSILE,MES_PCS_NOISE_CONFORMANCE,MES_PCS_DARK_CURRENT,MES_PCS_SCOOTERS_RAIN,MES_PCS_SIMULATE_WASH,MES_PCS_FRONT_REAR_SUSPENSION,MES_PCS_TRAVEL_ALTITUDE29,MES_PCS_WHITE_MEASUREMENT_DETECTION_11,MES_PCS_WHITE_MEASUREMENT_DETECTION_12,MES_PCS_WHITE_MEASUREMENT_DETECTION_13,MES_PCS_WHITE_MEASUREMENT_DETECTION_21,MES_PCS_WHITE_MEASUREMENT_DETECTION_22,MES_PCS_WHITE_MEASUREMENT_DETECTION_23,MES_PCS_ULTRASONIC_DETECTION11,MES_PCS_ULTRASONIC_DETECTION21,MES_PCS_ULTRASONIC_DETECTION22,MES_PCS_ULTRASONIC_DETECTION31,MES_PCS_ULTRASONIC_DETECTION32,MES_PCS_ULTRASONIC_DETECTION41,MES_PCS_ULTRASONIC_DETECTION42,MES_PCS_ULTRASONIC_DETECTION51,MES_PCS_ULTRASONIC_DETECTION52,MES_PCS_ULTRASONIC_DETECTION61,MES_PCS_ULTRASONIC_DETECTION62,MES_PCS_ULTRASONIC_DETECTION71,MES_PCS_ULTRASONIC_DETECTION72,MES_PCS_ULTRASONIC_DETECTION81,MES_PCS_WHITEBODY_WELDED11,MES_PCS_WHITEBODY_WELDED21,MES_PCS_WHITEBODY_WELDED22,MES_PCS_WHITEBODY_WELDED31,MES_PCS_WHITEBODY_WELDED41,MES_PCS_WHITEBODY_WELDED51,MES_PCS_WHITEBODY_WELDED61,MES_PCS_WHITEBODY_WELDED62,MES_PCS_WHITEBODY_WELDED71,MES_PCS_WHITEBODY_WELDED81,MES_PCS_WHITEBODY_WELDED91,MES_PCS_WHITEBODY_WELDED101,MES_PCS_WHITEBODY_WELDED111,MES_PCS_WHITEBODY_WELDED112,MES_PCS_WHITEBODY_WELDED121,MES_PCS_WHITEBODY_WELDED131,MES_PCS_WHITEBODY_WELDED141,MES_PCS_WHITEBODY_WELDED151,MES_PCS_WHITEBODY_WELDED161,MES_PCS_METALL_DETECTION1,MES_PCS_METALL_DETECTION2,MES_PCS_ELEC_THICK1,MES_PCS_ELEC_THICK2,MES_PCS_GLOSSY_TEMPLATE,MES_PCS_GAS_SEAL1,MES_PCS_GAS_SEAL2,MES_PCS_COAT_CFTEMPLATE,MES_PCS_PRE_ELEC_PROCECC1,MES_PCS_PRE_ELEC_PROCECC2,MES_PCS_GEL_MONITOR11,MES_PCS_GEL_MONITOR12,MES_PCS_GEL_MONITOR21,MES_PCS_GEL_MONITOR22,MES_PCS_TORQUE_SAMPLE,MES_PCS_TRANSMISSION_OIL,MES_PCS_ANTIFREEZE_ELEC,MES_PCS_REFRIGERANT_ELEC\n";
    private static final String tableNames = "MSG_LOG";
    private static final String author = "RJF";
    private static final String systemName = "wd-love";
    private static final String serviceName = "wd-love";
    //private static final String tablePrefixs = "TT_,TM_,TR_,TC_,TI_,TS_,TL_,UDA_";
    private static final String tablePrefixs = "UDA";

    private static final String parentPackage = "io.linfeng.api.app.mail";
    private static final String controllerPackage = "controller";
    //    private static final String controllerPackage = "modules.views.storeManagement.workshopMaterialDelivery.scanMaterialCardDelivery";
    private static final String servicePackage = "service";
    //    private static final String servicePackage = "service.storeManagement.workshopMaterialDelivery";
    private static final String serviceImplPackage = "service.impl";
    //    private static final String serviceImplPackage = "service.impl.storeManagement.workshopMaterialDelivery";
    private static final String entityPackage = "pojo.entity";
    private static final String mapperPackage = "mapper";
//    private static final String mapperPackage = "mapper.storeManagement.workshopMaterialDelivery";

    //数据库配置
//    private static final String driverClassName = "oracle.jdbc.driver.OracleDriver";
//    private static final String url = "jdbc:oracle:thin:@10.140.2.93:1521/czmes";
//    private static final String username = "czmes";
//    private static final String password = "czmes#2022";

//    private static final String driverClassName = "oracle.jdbc.driver.OracleDriver";
    //    private static final String url = "jdbc:oracle:thin:@10.12.16.16:1521/ORCLPDB1";
    private static final String driverClassName = "com.mysql.cj.jdbc.Driver";
//    private static final String url = "jdbc:oracle:thin:@10.104.250.171:1521:LMSDT";
    private static final String url = "jdbc:mysql://117.78.5.218:3306/huaweiyun?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false";
    //    private static final String username = "LMS";
    //    private static final String password = "Catarc1234";

    private static final String username = "huaweiyun";
    private static final String password = "HuaWeiYun@1234.";

    private static final String JAVA_SOURCE_PATH = System.getProperty("user.dir") + "\\hunlian-back\\src\\main\\java";
    private static final String XML_SOURCE_PATH = System.getProperty("user.dir") + "\\hunlian-back\\src\\main\\resources\\mapper";
    //private static final String VO_SOURCE_PATH = System.getProperty("user.dir") + "/src/main/java/simple/deliverance/model/";
    private static final String VUE_SOURCE_PATH = "C:\\Users\\R26\\Desktop\\vue\\views\\";
    private static final String JS_SOURCE_PATH = "C:\\Users\\R26\\Desktop\\vue\\js\\";


    public static void main(String[] args) throws InterruptedException {

        AutoGenerator mpg = new AutoGenerator();

        // 全局配置
        mpg.setGlobalConfig(getGlobalConfig(JAVA_SOURCE_PATH));

        // 数据源配置
        mpg.setDataSource(getDataSourceConfig());

        // 策略配置
        mpg.setStrategy(getStrategyConfig(tableNames.split(","), tablePrefixs.split(",")));

        // 配置包结构
        mpg.setPackageInfo(getPackageConfig());

        // mapper.xml配置
        mpg.setCfg(getInjectionConfig());

        //模板配置
        mpg.setTemplate(getTemplateConfig());

        // 执行
        mpg.execute();
    }

    private static InjectionConfig getInjectionConfig() {
        // 注入自定义配置
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                Map<String, Object> map = new HashMap<String, Object>(2);
                map.put("dollar", "$");
                map.put("systemName", systemName);
                map.put("serviceName", serviceName);
                map.put("voPackage", parentPackage + ".model");
                this.setMap(map);
            }
        };
        // 修改xml生成目录
        List<FileOutConfig> focList = new ArrayList<FileOutConfig>();
        focList.add(new FileOutConfig("/templates/mapper.xml.vm") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                return XML_SOURCE_PATH + tableInfo.getEntityName().replace("Entity", "") + "Mapper.xml";
            }
        });


        // 自定义vue index生成目录
        focList.add(new FileOutConfig("/templates/index.vue.vm") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                return VUE_SOURCE_PATH + tableInfo.getEntityPath().replace("Entity", "") + "/index.vue";
            }
        });
        focList.add(new FileOutConfig("/templates/index.js.vm") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                return JS_SOURCE_PATH + tableInfo.getEntityPath().replace("Entity", "") + "/" + tableInfo.getEntityPath().replace("Entity", "") + ".js";
            }
        });

        cfg.setFileOutConfigList(focList);
        return cfg;
    }

    private static PackageConfig getPackageConfig() {
        PackageConfig pc = new PackageConfig();
        pc.setParent(parentPackage);
        if (StringUtils.isNotBlank(controllerPackage)) {
            pc.setController(controllerPackage);
        }
        if (StringUtils.isNotBlank(servicePackage)) {
            pc.setService(servicePackage);
        }

        if (StringUtils.isNotBlank(serviceImplPackage)) {
            pc.setServiceImpl(serviceImplPackage);
        }

        if (StringUtils.isNotBlank(entityPackage)) {
            pc.setEntity(entityPackage);
        }

        if (StringUtils.isNotBlank(mapperPackage)) {
            pc.setMapper(mapperPackage);
        }
        return pc;
    }

    private static StrategyConfig getStrategyConfig(String[] tableNames, String[] tablePrefixs) {
        StrategyConfig strategy = new StrategyConfig();
        //表名
        strategy.setInclude(tableNames);
        strategy.setTablePrefix(tablePrefixs);
        // 驼峰
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        return strategy;
    }

    /**
     * 设置数据源
     *
     * @return
     */
    private static DataSourceConfig getDataSourceConfig() {
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setDbType(DbType.MYSQL);
        dsc.setDriverName(driverClassName);
        dsc.setUrl(url);
        dsc.setUsername(username);
        dsc.setPassword(password);
        dsc.setTypeConvert(new MySqlTypeConvert() {
            @Override
            public DbColumnType processTypeConvert(GlobalConfig globalConfig, String fieldType) {
                //将数据库中datetime转换成date
                if (fieldType.toLowerCase().contains("datetime")) {
                    return DbColumnType.DATE;
                }
                return (DbColumnType) super.processTypeConvert(globalConfig, fieldType);
            }
        });

        return dsc;
    }

    /**
     * 全局配置
     *
     * @param outPutDir
     * @return
     */
    private static GlobalConfig getGlobalConfig(String outPutDir) {
        GlobalConfig gc = new GlobalConfig();
        gc.setOutputDir(outPutDir);
        // 是否覆盖
        gc.setFileOverride(false);
        //是否开启AR模式
        gc.setActiveRecord(true);
        gc.setEnableCache(false);
        gc.setBaseResultMap(true);
        gc.setBaseColumnList(true);
        gc.setAuthor(author);
        // 自定义文件命名，%s：文件名
        //gc.setEntityName("%sEntity");
        gc.setMapperName("%sMapper");
        gc.setXmlName("%sMapper");
        gc.setServiceName("%sService");
        gc.setServiceImplName("%sServiceImpl");
        gc.setControllerName("%sController");
        return gc;
    }

    private static TemplateConfig getTemplateConfig() {
        // 删除默认的xml生成
        TemplateConfig tc = new TemplateConfig();
        tc.setXml(null);
        if (StringUtils.isBlank(controllerPackage)) {
            tc.setController(null);
        } else {
            tc.setController("/templates/controller.java.vm");
        }
        if (StringUtils.isBlank(servicePackage)) {
            tc.setService(null);
        } else {
            tc.setService("/templates/service.java.vm");
        }
        if (StringUtils.isBlank(serviceImplPackage)) {
            tc.setServiceImpl(null);
        } else {
            tc.setServiceImpl("/templates/serviceImpl.java.vm");
        }
        if (StringUtils.isBlank(entityPackage)) {
            tc.setEntity(null);
        } else {
            tc.setEntity("/templates/entity.java.vm");
        }
        if (StringUtils.isBlank(mapperPackage)) {
            tc.setMapper(null);
        } else {
            tc.setMapper("/templates/mapper.java.vm");
        }
        return tc;
    }
}
